package com.core.family.admin.service.Impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.core.common.exception.BDException;
import com.core.common.gen.BaseQuery;
import com.core.common.utils.springutils.ApplicationUtil;
import com.core.family.admin.domain.req.DictReq;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

import com.core.family.admin.mapper.DictMapper;
import com.core.family.admin.domain.Dict;
import com.core.family.admin.service.DictService;
import com.core.common.gen.BaseServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;


/**
 * @author honglei
 * @version 1.0
 * @time: 2024-6-14 10:14:21
 * @Description 服务实现层 字典
 */
@Slf4j
@Service
public class DictServiceImpl extends BaseServiceImpl<DictMapper, Dict> implements DictService {

    private static Map<String,Set<String>> dictMap = new HashMap<>();
    @Value("${spring.cache.offset}")
    private int offset;


    public Integer getLevel(Serializable parentId) {
        if (StringUtils.isEmpty(parentId)) {
            throw new BDException("字典父级id不能为空");
        }
        Dict pDict = getById(parentId);
        int level = null == pDict ? 0 : pDict.getLevel() + 1;
        return level;
    }

    public Integer getNextCode(Dict dict) {
        if (dict == null) {
            throw new BDException("字典父级id不能为空");
        }
        if (dict.getParentId() == null) {
            throw new BDException("字典父级id不能为空");
        }
        Integer suq = Optional.ofNullable(this.baseMapper.getNextCode(dict)).orElse(0);
        return ++suq;
    }


    @Cacheable(value = "Dict.selectPage",keyGenerator = "myKeyGen")
    @Override
    public IPage<Dict> selectPage(BaseQuery baseQuery) {
        IPage<Dict> page = super.selectPage(baseQuery);
        for (Dict record : page.getRecords()) {
            if (getAllParentId().contains(record.getParentId())){
                record.setHasChildren(true);
            }
        }
        return page;
    }

    @Cacheable(value = "Dict.selectList",keyGenerator = "myKeyGen")
    @Override
    public List<Dict> selectList(BaseQuery queryBean) {
        List<Dict> list=super.selectList(queryBean);
        list.stream().forEach(dict->{
            if (ApplicationUtil.getBean(DictService.class).getAllParentId()
                    .contains(dict.getId())){
                dict.setHasChildren(true);
            }
        });
        return list;
    }


    @Cacheable(value = "dict.getAllParentId",keyGenerator = "myKeyGen")
    public Set<String> getAllParentId(){
        if (! dictMap.isEmpty()){
            Iterator<String> it=dictMap.keySet().iterator();
            while (it.hasNext()){
                String key=it.next();
                DateTime dateTime= DateUtil.parse(key);
                DateTime nowTime=DateTime.now();
                if (dateTime.isBefore(nowTime)){
                    it.remove();
                }else {
                    return dictMap.get(key);
                }
            }
        }
        Set<String> parentidSet=new HashSet<>();
        list().stream().forEach(dict->{parentidSet.add(dict.getParentId());});
        String time = DateTime.now().offset(DateField.MINUTE,offset).toString("yyyyMMddHHmmss");
        dictMap.put(time,parentidSet);
        return parentidSet;


    }

    @Override
    public boolean save(Dict dict) {
        if (dict == null) {
            return false;
        }
        if (StringUtils.isEmpty(dict.getParentId())) {
            throw new BDException("父级id不能为空");
        }
        dict.setLevel(getLevel(dict.getParentId()));
        if (StringUtils.isEmpty(dict.getDictSort())) {
            dict.setDictSort(getNextCode(dict));
        }
        if (StringUtils.isEmpty(dict.getDictCode())) {
            dict.setDictCode(dict.getParentId() + "-" + getNextCode(dict));
        }
        return super.save(dict);
    }

    @Override
    public boolean updateById(Dict entity) {
        if (entity == null || null == entity.getId()) {
            return false;
        }
        return super.updateById(entity);
    }

    @Override
    public boolean saveOrUpdate(Dict dict) {
        if (dict == null) {
            return false;
        }
        if (StringUtils.isEmpty(dict.getParentId())) {
            throw new BDException("父级id不能为空");
        }
        dict.setLevel(getLevel(dict.getParentId()));
        if (StringUtils.isEmpty(dict.getDictSort())) {
            dict.setDictSort(getNextCode(dict));
        }
        if (StringUtils.isEmpty(dict.getDictCode())) {
            dict.setDictCode(dict.getParentId() + "-" + getNextCode(dict));
        }

        UpdateWrapper<Dict> wrapper = new UpdateWrapper<>();
        wrapper.lambda()
                .eq(Dict::getDictCode, dict.getDictCode())
                .eq(Dict::getDictName, dict.getDictName());
        Dict db = getOne(wrapper, false);
        if (Objects.nonNull(db)) {
            dict.setId(db.getId());
        }
        return super.saveOrUpdate(dict);
    }


    public boolean saveDictFamily(Dict dict) {
        boolean bl = saveOrUpdate(dict);
        if (bl && !CollectionUtils.isEmpty(dict.getChildren())) {
            for (Dict dictsub : dict.getChildren()) {
                dictsub.setParentId(dict.getId());
                saveDictFamily(dictsub);
            }
        }
        return true;
    }

    public List<Dict> listTree(DictReq queryReq) {
        //获取所有菜单
        List<Dict> list = ApplicationUtil.getBean(DictService.class).selectList(queryReq);
        //筛选一级数据
        List<Dict> leve1Datas = list.stream()
                .filter(o -> o.getParentId().equals("0"))
                .map(bean -> {
                    List<Dict> children = getChildren(bean, list);
                    if (!CollectionUtils.isEmpty(children)) {
                        bean.setChildren(children);
                    }
                    return bean;
                })
                .sorted(Comparator.comparingInt(menu -> (BeanUtil.isEmpty(menu.getDictSort()) ? 0 : menu.getDictSort())))
                .collect(Collectors.toList());
        return leve1Datas;
    }


    /**
     * 递归查询类
     *
     * @param dict
     * @param list
     * @return
     */
    private List<Dict> getChildren(Dict dict, List<Dict> list) {
        //筛选出父类
        List<Dict> collect = list.stream()
                .filter(o -> dict.getId().equals(o.getParentId()))
                .map(cat -> {
                    List<Dict> children = getChildren(cat, list);
                    if (!CollectionUtils.isEmpty(children)) {
                        cat.setChildren(children);
                    }
                    return cat;
                })
                .sorted(Comparator.comparingInt(bean -> (BeanUtil.isEmpty(bean.getDictSort()) ? 0 : bean.getDictSort())))
                .collect(Collectors.toList());
        return collect;
    }


}

